package javango.db;

import com.google.inject.Binding;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;

public abstract class AbstractManagers implements Managers {

	Injector injector;
	
	@Inject
	public AbstractManagers(Injector injector) {
		super();
		this.injector = injector;
	}

	@SuppressWarnings("unchecked")
	public <T> Manager<T> forClass(Class<T> model) {
	    final Key<Manager> key = Key.get(Manager.class, Names.named(model.getName()));
	    if (key != null) {
	    	Binding binding = injector.getBindings().get(key);
	    	if (binding != null) {
	    		return (Manager<T>) binding.getProvider().get();
	    	}
	    }
	    
		ManagedBy by = model.getAnnotation(ManagedBy.class);
		if (by == null) {
			return getForClass(model);
		}
		
		return (Manager<T>)injector.getInstance(by.value());
	}
	
	
// is this needed?	
	public <T> Manager<T> forClass(Class<T> model, Class<? extends T> impl) {

	    final Key<Manager> key = Key.get(Manager.class, Names.named(model.getName()));
	    if (key != null) {
	    	Binding binding = injector.getBindings().get(key);
	    	if (binding != null) {
	    		return (Manager<T>) binding.getProvider().get();
	    	}
	    }
	    
		ManagedBy by = impl.getAnnotation(ManagedBy.class);
		if (by == null) {
			return getForClass(impl);
		}

		by = model.getAnnotation(ManagedBy.class);
		if (by == null) {
			return getForClass(impl);
		}
		
		return (Manager<T>)injector.getInstance(by.value());
	}
	abstract protected <T> Manager<T> getForClass(Class<? extends T> model);
}
